
package com.heimali.happyreader.core.manager;

import com.heimali.happyreader.core.bean.ActionPublisherWithThreadPoolBase;
import com.heimali.happyreader.core.bean.Article;
import com.heimali.happyreader.core.bean.Intro;
import com.heimali.happyreader.core.bean.ManagedRuntimeException;
import com.heimali.happyreader.core.bean.PoolThreadFactory;
import com.heimali.happyreader.core.intf.ITaskListenerSimple;
import com.heimali.happyreader.core.net.ArticleApi;
import com.heimali.happyreader.utils.Utils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;

public class ArticleManager extends ActionPublisherWithThreadPoolBase {
    public static String TAG = "ArticleManager";
    private String mPoolNameHighPriority;
    private String mPoolNameLowPriority;
    private ArticleApi mApi;
    
    public ArticleManager() {
        mApi = new ArticleApi();
        mPoolNameLowPriority = "pool-worker-low-priority-" + Utils.DATE_FORMAT_3.format(new Date());
        mPoolNameHighPriority = "pool-worker-high-priority-" + Utils.DATE_FORMAT_3.format(new Date());
        mThreadPool.initPool(mPoolNameLowPriority, Executors.newCachedThreadPool(new PoolThreadFactory(mPoolNameLowPriority)));
        mThreadPool.initPool(mPoolNameHighPriority, Executors.newCachedThreadPool(new PoolThreadFactory(mPoolNameHighPriority)));
    }

    @Override
    protected void asyncDoNamedJob(String jobName, Object... args) {
        if ("load-list".equals(jobName)) {
            doLoadList((ITaskListenerSimple) args[0], (Integer) args[1], (Integer) args[2]);
        } else if ("load-lastest-list".equals(jobName)) {
            doLoadLastestList((ITaskListenerSimple) args[0], (Integer) args[1]);
        } else if ("load-detail".equals(jobName)) {
            doLoadDetail((ITaskListenerSimple) args[0], (Integer) args[1]);
        }
    }

    public void asyncLoadList(ITaskListenerSimple taskListener, int start, int count) {
        mThreadPool.submit(mPoolNameHighPriority, new NamedAsyncJob("load-list", taskListener, start, count));
    }

    private void doLoadList(final ITaskListenerSimple taskListener, int start, int count) {
        try {
            final List<Intro> list = new ArrayList<Intro>();
            list.addAll(mApi.getList(start, count));
            publishFinished(taskListener, list);
        } catch (ManagedRuntimeException e) {
            publishFailed(taskListener, e);
        }
    }

    public void asyncLoadLastestList(ITaskListenerSimple taskListener, int maxID) {
        mThreadPool.submit(mPoolNameHighPriority, new NamedAsyncJob("load-lastest-list", taskListener, maxID));
    }

    private void doLoadLastestList(final ITaskListenerSimple taskListener, int maxID) {
        try {
            final List<Intro> list = new ArrayList<Intro>();
            list.addAll(mApi.getLastestList(maxID));
            publishFinished(taskListener, list);
        } catch (ManagedRuntimeException e) {
            publishFailed(taskListener, e);
        }
    }

    public void asyncLoadDetail(ITaskListenerSimple taskListener, int id) {
        mThreadPool.submit(mPoolNameHighPriority, new NamedAsyncJob("load-detail", taskListener, id));
    }

    private void doLoadDetail(final ITaskListenerSimple taskListener, int id) {
        try {
            final Article article = mApi.getDetail(id);
            publishFinished(taskListener, article);
        } catch (ManagedRuntimeException e) {
            publishFailed(taskListener, e);
        }
    }

    private void publishFinished(final ITaskListenerSimple taskListener, final Object obj) {
        if (isStopped()) {
            return ;
        }
        mUiHandler.post(new Runnable() {
            @Override
            public void run() {
                taskListener.taskFinished(obj);
            }
        });
    }
    
    private void publishFailed(final ITaskListenerSimple taskListener, final Object obj) {
        if (isStopped()) {
            return ;
        }
        mUiHandler.post(new Runnable() {
            @Override
            public void run() {
                taskListener.taskFailed(obj);
            }
        });
    }
}
